import tkinter as tk
from tkinter import ttk, messagebox
import paramiko
from threading import Thread
import queue

class RemoteShellGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("远程服务器管理工具")
        
        # SSH 客户端
        self.ssh_client = None
        self.output_queue = queue.Queue()
        
        # 创建主框架
        self.create_gui()
        
        # 定期检查输出
        self.check_output()

    def create_gui(self):
        # 连接框架
        self.conn_frame = ttk.LabelFrame(self.root, text="SSH连接", padding="5")
        self.conn_frame.grid(row=0, column=0, padx=5, pady=5, sticky="ew")
        
        # 服务器信息输入
        ttk.Label(self.conn_frame, text="主机:").grid(row=0, column=0, padx=5)
        self.host_entry = ttk.Entry(self.conn_frame, width=15)
        self.host_entry.grid(row=0, column=1, padx=5)
        
        ttk.Label(self.conn_frame, text="端口:").grid(row=0, column=2, padx=5)
        self.port_entry = ttk.Entry(self.conn_frame, width=6)
        self.port_entry.insert(0, "22")
        self.port_entry.grid(row=0, column=3, padx=5)
        
        ttk.Label(self.conn_frame, text="用户名:").grid(row=0, column=4, padx=5)
        self.username_entry = ttk.Entry(self.conn_frame, width=15)
        self.username_entry.grid(row=0, column=5, padx=5)
        
        ttk.Label(self.conn_frame, text="密码:").grid(row=0, column=6, padx=5)
        self.password_entry = ttk.Entry(self.conn_frame, width=15, show="*")
        self.password_entry.grid(row=0, column=7, padx=5)
        
        self.connect_btn = ttk.Button(self.conn_frame, text="连接", command=self.connect_ssh)
        self.connect_btn.grid(row=0, column=8, padx=5)
        
        self.disconnect_btn = ttk.Button(self.conn_frame, text="断开", command=self.disconnect_ssh, state='disabled')
        self.disconnect_btn.grid(row=0, column=9, padx=5)
        
        # 命令框架
        self.cmd_frame = ttk.LabelFrame(self.root, text="命令执行", padding="5")
        self.cmd_frame.grid(row=1, column=0, padx=5, pady=5, sticky="ew")
        
        # 命令输入框
        self.cmd_entry = ttk.Entry(self.cmd_frame, width=70)
        self.cmd_entry.grid(row=0, column=0, padx=5, pady=5)
        
        # 执行按钮
        self.run_btn = ttk.Button(self.cmd_frame, text="执行", command=self.run_command, state='disabled')
        self.run_btn.grid(row=0, column=1, padx=5, pady=5)
        
        # 清除按钮
        self.clear_btn = ttk.Button(self.cmd_frame, text="清除", command=self.clear_output)
        self.clear_btn.grid(row=0, column=2, padx=5, pady=5)
        
        # 输出文本框
        self.output_text = tk.Text(self.root, height=20, width=100)
        self.output_text.grid(row=2, column=0, padx=5, pady=5)
        
        # 滚动条
        scrollbar = ttk.Scrollbar(self.root, orient=tk.VERTICAL, command=self.output_text.yview)
        scrollbar.grid(row=2, column=1, sticky=tk.NS)
        self.output_text['yscrollcommand'] = scrollbar.set
        
        # 绑定回车键
        self.cmd_entry.bind('<Return>', lambda e: self.run_command())

    def connect_ssh(self):
        host = self.host_entry.get()
        port = int(self.port_entry.get())
        username = self.username_entry.get()
        password = self.password_entry.get()
        
        if not all([host, username, password]):
            messagebox.showerror("错误", "请填写完整的连接信息")
            return
            
        try:
            self.ssh_client = paramiko.SSHClient()
            self.ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            self.ssh_client.connect(host, port, username, password)
            
            self.output_queue.put(f"成功连接到 {host}\n")
            self.connect_btn.state(['disabled'])
            self.disconnect_btn.state(['!disabled'])
            self.run_btn.state(['!disabled'])
            
        except Exception as e:
            messagebox.showerror("连接错误", str(e))
            self.ssh_client = None

    def disconnect_ssh(self):
        if self.ssh_client:
            self.ssh_client.close()
            self.ssh_client = None
            self.output_queue.put("已断开连接\n")
            self.connect_btn.state(['!disabled'])
            self.disconnect_btn.state(['disabled'])
            self.run_btn.state(['disabled'])

    def run_command(self):
        if not self.ssh_client:
            messagebox.showerror("错误", "请先连接到服务器")
            return
            
        command = self.cmd_entry.get()
        if command:
            self.cmd_entry.delete(0, tk.END)
            Thread(target=self.execute_command, args=(command,), daemon=True).start()

    def execute_command(self, command):
        try:
            self.run_btn.state(['disabled'])
            stdin, stdout, stderr = self.ssh_client.exec_command(command)
            
            # 读取输出
            for line in stdout:
                self.output_queue.put(line)
            for line in stderr:
                self.output_queue.put(f"错误: {line}")
                
        except Exception as e:
            self.output_queue.put(f"执行错误: {str(e)}\n")
        finally:
            self.root.after(100, lambda: self.run_btn.state(['!disabled']))

    def check_output(self):
        """定期检查并显示输出"""
        while not self.output_queue.empty():
            line = self.output_queue.get()
            self.output_text.insert(tk.END, line)
            self.output_text.see(tk.END)
        
        self.root.after(100, self.check_output)

    def clear_output(self):
        """清除输出文本框"""
        self.output_text.delete(1.0, tk.END)

if __name__ == "__main__":
    root = tk.Tk()
    app = RemoteShellGUI(root)
    root.mainloop()